//
//  NSConditionLockDemo.swift
//  sinaDemo
//
//  Created by admin on 2021/7/14.
//

import UIKit

class NSConditionLockDemo: LockBase {
    //默认条件就是0
    /*
     NSConditionLock 是锁，一旦一个线程获得锁，其他线程一定等待
     [xxxx lock]; 表示 xxx 期待获得锁，如果没有其他线程获得锁（不需要判断内部的condition)那它能执行此行以下代码，如果已经有其他线程获得锁（可能是条件锁，或者无条件锁）， 则等待，直至其他线程解锁
     [xxx lockWhenCondition:A条件]; 表示如果没有其他线程获得该锁，但是该锁内部的condition不等于A条件，它依然不能获得锁，仍然等待。如果内部的condition等于A条件，并且没有其他线程获得该锁，则进入代码区，同时设置它获得该锁，其他任何线程都将等待它代码的完成，直至它解锁。
     [xxx unlockWithCondition:A条件]; 表示释放锁，同时把内部的condition设置为A条件
     return = [xxx lockWhenCondition:A条件 beforeDate:A时间]; 表示如果被锁定（没获得锁），并超过该时间则不再阻塞线程。但是注意：返回的值是NO,它没有改变锁的状态， 这个函数的目的在于可以实现两种状态下的处理
     所谓的condition就是整数，内部通过整数比较条件
     */
    var conditionLock:NSConditionLock = NSConditionLock.init()
    override init() {
        super.init()
        test()
    }
    private func test(){
        DispatchQueue.global().async {
            self.condLockTest()
        }
        DispatchQueue.global().async {
            self.condLockTest1()
        }
        DispatchQueue.global().async {
            self.condLockTest2()
        }
        
    }
    /*
     条件锁，举个例子🌰（同一个数组，一个add 另一个remove，remove得等数组不为空才remove，但是不同的异步线程进行增删操作。所以可以用到条件锁开进行控制）
     */
    //条件锁的测试
    private func condLockTest(){
        //加锁，条件是0时
        conditionLock.lock(whenCondition: 0)
        sleep(2)
        print("condLockTest")
        
        print("继续执行condLockTest")
        //解锁并将条件置为1
        conditionLock.unlock(withCondition: 1)
    }
    private func condLockTest1(){
        //加锁，当条件为1时才有可能会拿到锁
        conditionLock.lock(whenCondition: 1)
        print("condLockTest1")

        print("继续执行condLockTest1")
        //解锁
        conditionLock.unlock(withCondition: 2)
    }
    private func condLockTest2(){
        //加锁，当条件为2时才有可能会拿到锁
        conditionLock.lock(whenCondition: 2)
        print("condLockTest2")

        print("继续执行condLockTest2")
        //解锁
        conditionLock.unlock(withCondition: 3)
    }
}
